﻿/*
 * EmeCoder v1.2.1.168
 * 作者：Administrator/PC4APPLE
 * 时间：2013-08-22 13:28:39
 * 版权：版权所有 (C) Eme Development Team 2013
*/

﻿using System;
using System.ComponentModel;
using System.Xml.Serialization;
using HmFramework.Data;

namespace CuteSprite.Eme.Data.Settlement
{
	/// <summary>计费价格方案</summary>
	[Serializable]
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class PriceSolution : PriceSolution<PriceSolution> { }

	/// <summary>计费价格方案</summary>
	public partial class PriceSolution<TEntity> : Entity<TEntity> where TEntity : PriceSolution<TEntity>, new()
	{
		#region 对象操作﻿

		static PriceSolution()
		{
			// 用于引发基类的静态构造函数，所有层次的泛型实体类都应该有一个
			TEntity entity = new TEntity();
		}

		/// <summary>验证数据，通过抛出异常的方式提示验证失败。</summary>
		/// <param name="isNew"></param>
		public override void Valid(Boolean isNew)
		{
			// 这里验证参数范围，建议抛出参数异常，指定参数名，前端用户界面可以捕获参数异常并聚焦到对应的参数输入框
			//if (MatchHelper.StrIsNullOrEmpty(Name)) throw new ArgumentNullException(_.Name, _.Name.DisplayName + "无效！");
			//if (!isNew && ID < 1) throw new ArgumentOutOfRangeException(_.ID, _.ID.DisplayName + "必须大于0！");

			// 建议先调用基类方法，基类方法会对唯一索引的数据进行验证
			base.Valid(isNew);
			// 在新插入数据或者修改了指定字段时进行唯一性验证，CheckExist内部抛出参数异常
			//if (isNew || Dirtys[__.Name]) CheckExist(__.Name);
			// 货币保留6位小数
			if (Dirtys[__.WeightBasedBilling]) WeightBasedBilling = Math.Round(WeightBasedBilling, 6);

			// 货币保留6位小数
			if (Dirtys[__.PrimaryPrice]) PrimaryPrice = Math.Round(PrimaryPrice, 6);

			// 货币保留6位小数
			if (Dirtys[__.ExtraPrice]) ExtraPrice = Math.Round(ExtraPrice, 6);

			if (isNew)
			{
				//if (!Dirtys[__.CreateOn]) { CreateOn = DateTime.Now; }
				CreateOn = DateTime.Now;
			}
			else if (HasDirty)
			{
				//if (!Dirtys[__.ModifiedOn]) { ModifiedOn = DateTime.Now; }
				ModifiedOn = DateTime.Now;
			}
		}

		///// <summary>已重载。基类先调用Valid(true)验证数据，然后在事务保护内调用OnInsert</summary>
		///// <returns></returns>
		//public override Int32 Insert()
		//{
		//    return base.Insert();
		//}

		///// <summary>已重载。在事务保护范围内处理业务，位于Valid之后</summary>
		///// <returns></returns>
		//protected override Int32 OnInsert()
		//{
		//    return base.OnInsert();
		//}

		#endregion

		#region 扩展属性﻿

		//[NonSerialized]
		//private BillingSolution _BillingSolution;
		/// <summary>该计费价格方案所对应的计费方案</summary>
		[XmlIgnore]
		public BillingSolution BillingSolution
		{
			get
			{
				return Extends.GetExtend<BillingSolution, BillingSolution>("BillingSolution", e => BillingSolution.FindByID(BillingSolutionID));
				//if (_BillingSolution == null && BillingSolutionID > 0 && !Dirtys.ContainsKey("BillingSolution"))
				//{
				//	_BillingSolution = BillingSolution.FindByID(BillingSolutionID);
				//	Dirtys["BillingSolution"] = true;
				//}
				//return _BillingSolution;
			}
			set { Extends.SetExtend<BillingSolution>("BillingSolution", value); }
		}

		#endregion

		#region 扩展查询﻿

		/// <summary>根据计费方案查找</summary>
		/// <param name="billingsolutionid">计费方案</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static EntityList<TEntity> FindAllByBillingSolutionID(Int32 billingsolutionid)
		{
			if (Meta.Count > 1000)
				return FindAll(_.BillingSolutionID, billingsolutionid);
			else // 实体缓存
				return Meta.Cache.Entities.FindAll(__.BillingSolutionID, billingsolutionid);
		}

		/// <summary>根据主键查找</summary>
		/// <param name="id">主键</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static TEntity FindByID(Int32 id)
		{
			if (Meta.Count > 1000)
				return Find(_.ID, id);
			else // 实体缓存
				return Meta.Cache.Entities.Find(_.ID, id);

			// 单对象缓存
			//return Meta.SingleCache[id];
		}

		#endregion

		#region 扩展操作

		#endregion

		#region 业务

		/// <summary>根据当前方案重量基数(0.5或1)格式化运单重量</summary>
		/// <param name="weight"></param>
		/// <param name="weightBasedBilling">重量基数</param>
		/// <returns></returns>
		public static Decimal FormatWeight(Decimal weight, Decimal weightBasedBilling)
		{
			if (weightBasedBilling == 1M)
			{
				return Math.Ceiling(weight);
			}
			else
			{
				var v = Math.Truncate(weight);
				var mod = weight % 1;
				if (v > 0M)
				{
					if (mod == 0M)
					{
						return v;
					}
					else
					{
						if (mod > 0.5M)
						{
							return Math.Ceiling(weight);
						}
						else
						{
							return v + 0.5M;
						}
					}
				}
				else
				{
					if (mod > 0.5M)
					{
						return Math.Ceiling(weight);
					}
					else
					{
						return 0.5M;
					}
				}
			}
		}

		#endregion
	}
}